﻿#region Licence
// $Id: image_change_original_dt.pl 5 2010-08-03 19:42:24Z halyava $
// Copyright (c) 2010 Ivan Nevostruev (halyava@gmail.com)
// 
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
// 
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
// 
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using System.Windows.Forms;

using ExifUtils.Exif;
using ExifUtils.Exif.IO;
using ExifUtils.Exif.TagValues;

namespace mass_image_property_changer
{
    public partial class MainForm : Form
    {
        private DateTime last_date_used;

        public MainForm()
        {
            InitializeComponent();
            textFolderName.Text = Properties.Settings.Default.lastFolderSelected;
            if (textFolderName.Text.Length > 0)
            {
                info("last folder [" + textFolderName.Text + "]");
            }
        }

        private void buttonBrowse_Click(object sender, EventArgs e)
        {
            folderBrowserDialog.ShowDialog();
            textFolderName.Text = folderBrowserDialog.SelectedPath;
        }

        private void textFolderName_TextChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.lastFolderSelected = textFolderName.Text;
            folderBrowserDialog.SelectedPath = textFolderName.Text;
            updateConvertButton();
        }

        private void info(string message)
        {
            logText.Text = DateTime.Now.ToString() + ": " + message + "\r\n" + logText.Text;
        }

        private void updateConvertButton() 
        {
            if (Directory.Exists(textFolderName.Text))
            {
                buttonConvert.Enabled = ! jobConvert.IsBusy;
            }
            else 
            {
                buttonConvert.Enabled = false;
                info("folder [" + textFolderName.Text + "] is not found");
            }
        }

        private void buttonConvert_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(
                "You are going to convert images in [" + textFolderName.Text + "] folder. WARNING: Image creation date will be lost. Make sure that you've backuped your files.\r\n\r\n Are you sure to convert these files?",
                "Do you want to convert images?",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Warning
            ) == DialogResult.Yes)
            {
                info("start file sorting in [" + textFolderName.Text + "]");
                jobConvert.RunWorkerAsync();
                updateConvertButton();
            }
        }

        private void jobConvert_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] files = Directory.GetFiles(textFolderName.Text, "*.jpg", SearchOption.AllDirectories);
            Array.Sort(files, SafeNativeMethods.StrCmpLogicalW);

            List<string> errors = new List<string>();
            if (files.Length > 0) {
                last_date_used = DateTime.Now;
                last_date_used = last_date_used.AddMinutes(-(10 + files.Length));
                int processed_count = 0;
                foreach (string file in files)
                {
                    try
                    {
                        jobConvert.ReportProgress(1 + (1000 * (processed_count++) / files.Length));
                        set_creation_date(file, next_datetime());
                    }
                    catch (Exception exp)
                    {
                        errors.Add("ERROR in [" + file + "]: " + exp.Message);
                    }
                }
            }
            jobConvert.ReportProgress(1000);
            errors.Add(files.Length + " file" + (files.Length==1?" was":"s were")  + " converted");
            e.Result = errors.ToArray();
        }

        private string next_datetime()
        {
            last_date_used = last_date_used.AddMinutes(1);
            return last_date_used.ToString("yyyy:MM:dd HH:mm:ss");
        }
        
        private void set_creation_date(string file_name, string datetime) 
        {
            ExifPropertyCollection properties = ExifReader.GetExifData(file_name);
            ExifProperty original_dt = new ExifProperty();
            original_dt.Tag = ExifTag.DateTimeOriginal;
            original_dt.Value = datetime;
            ExifWriter.AddExifData(file_name, file_name + ".jpg", original_dt);
            File.Delete(file_name);
            File.Move(file_name + ".jpg", file_name);
        }

        private void jobConvert_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            updateConvertButton();
            string[] result = (string[]) e.Result;
            foreach (string msg in result)
            {
                info(msg);
            }
            info("end sorting");
        }

        private void jobConvert_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBarConvertion.Value = e.ProgressPercentage;
        }

        private void buttonAbout_Click(object sender, EventArgs e)
        {
            AboutBox box = new AboutBox();
            box.ShowDialog();
        }

    }
}
